package types

import (
	"encoding/json"
)

// StatementType SQL语句类型枚举
type StatementType string

const (
	StatementTypeCreateTable StatementType = "CREATE_TABLE"
	StatementTypeCreateIndex StatementType = "CREATE_INDEX"
	StatementTypeAlterTable  StatementType = "ALTER_TABLE"
	StatementTypeDropTable   StatementType = "DROP_TABLE"
	StatementTypeTruncate    StatementType = "TRUNCATE_TABLE"
	StatementTypeSelect      StatementType = "SELECT"
	StatementTypeInsert      StatementType = "INSERT"
	StatementTypeUpdate      StatementType = "UPDATE"
	StatementTypeDelete      StatementType = "DELETE"
	StatementTypeComment     StatementType = "COMMENTSTMT"
	StatementTypeUnknown     StatementType = "UNKNOWN"
)

// String 实现Stringer接口
func (st StatementType) String() string {
	return string(st)
}

// IsValid 检查是否为有效的语句类型
func (st StatementType) IsValid() bool {
	switch st {
	case StatementTypeCreateTable, StatementTypeCreateIndex, StatementTypeAlterTable,
		StatementTypeDropTable, StatementTypeTruncate, StatementTypeSelect,
		StatementTypeInsert, StatementTypeUpdate, StatementTypeDelete, StatementTypeComment, StatementTypeUnknown:
		return true
	default:
		return false
	}
}

// IsDDL 检查是否为DDL语句类型
func (st StatementType) IsDDL() bool {
	switch st {
	case StatementTypeCreateTable, StatementTypeCreateIndex, StatementTypeAlterTable,
		StatementTypeDropTable, StatementTypeTruncate, StatementTypeComment:
		return true
	default:
		return false
	}
}

// IsDML 检查是否为DML语句类型
func (st StatementType) IsDML() bool {
	switch st {
	case StatementTypeSelect, StatementTypeInsert, StatementTypeUpdate, StatementTypeDelete:
		return true
	default:
		return false
	}
}

// ParserUsed 使用的解析器枚举
type ParserUsed string

const (
	ParserUsedPgQuery ParserUsed = "PG_QUERY"
	ParserUsedTiDB    ParserUsed = "TIDB"
	ParserUsedUnknown ParserUsed = "UNKNOWN"
)

// String 实现Stringer接口
func (pu ParserUsed) String() string {
	return string(pu)
}

// IsValid 检查是否为有效的解析器类型
func (pu ParserUsed) IsValid() bool {
	switch pu {
	case ParserUsedPgQuery, ParserUsedTiDB, ParserUsedUnknown:
		return true
	default:
		return false
	}
}

// SQLStatement 表示一个SQL语句的通用结构
type SQLStatement struct {
	// 基础信息
	OriginalSQL   string        `json:"original_sql"`
	StatementType StatementType `json:"statement_type"`
	ParserUsed    ParserUsed    `json:"parser_used"`

	// 表和列信息
	TableName string   `json:"table_name,omitempty"`
	Schema    string   `json:"schema,omitempty"`
	Tables    []string `json:"tables,omitempty"`
	Columns   []string `json:"columns,omitempty"`

	// 解析结果
	Statement  interface{}            `json:"-"`
	ParsedJSON map[string]interface{} `json:"parsed_json,omitempty"`

	// 操作信息
	Operations []string `json:"operations,omitempty"`

	// 验证状态
	IsValid bool   `json:"is_valid"`
	Error   string `json:"error,omitempty"`
}

// NewSQLStatement 创建新的SQL语句实例
func NewSQLStatement(originalSQL string) *SQLStatement {
	return &SQLStatement{
		OriginalSQL:   originalSQL,
		StatementType: StatementTypeUnknown,
		ParserUsed:    ParserUsedUnknown,
		Tables:        make([]string, 0),
		Columns:       make([]string, 0),
		Operations:    make([]string, 0),
		IsValid:       false,
	}
}

// GetRawSQL 获取原始SQL语句
func (s *SQLStatement) GetRawSQL() string {
	return s.OriginalSQL
}

// GetType 获取语句类型
func (s *SQLStatement) GetType() StatementType {
	return s.StatementType
}

// GetParser 获取使用的解析器
func (s *SQLStatement) GetParser() ParserUsed {
	return s.ParserUsed
}

// GetTableName 获取表名
func (s *SQLStatement) GetTableName() string {
	return s.TableName
}

// IsDDL 检查是否为DDL语句
func (s *SQLStatement) IsDDL() bool {
	return s.StatementType.IsDDL()
}

// IsDML 检查是否为DML语句
func (s *SQLStatement) IsDML() bool {
	return s.StatementType.IsDML()
}

// IsValid 检查语句是否有效
func (s *SQLStatement) IsValidStatement() bool {
	return s.IsValid && s.Error == ""
}

// ToJSON 转换为JSON字符串
func (s *SQLStatement) ToJSON() (string, error) {
	data, err := json.Marshal(s)
	if err != nil {
		return "", err
	}
	return string(data), nil
}

// FromJSON 从JSON字符串创建SQLStatement
func FromJSON(jsonStr string) (*SQLStatement, error) {
	var stmt SQLStatement
	err := json.Unmarshal([]byte(jsonStr), &stmt)
	if err != nil {
		return nil, err
	}
	return &stmt, nil
}
